/**
 * File MultiAgentSystem.java created by Pablo Díaz Fernández
 * on 28/10/2011 for the project supply-chain-simulator.
 */
package org.lsk.pfc.scsim.model.mas;

import jade.wrapper.AgentController;
import jade.wrapper.ContainerController;
import jade.wrapper.StaleProxyException;

import java.util.ArrayList;
import java.util.List;

import org.lsk.pfc.scsim.model.agent.InformationAgent;
import org.lsk.pfc.scsim.model.agent.UserAgent;
import org.lsk.pfc.scsim.model.exception.AgentException;
import org.lsk.pfc.scsim.model.exception.MASCreationException;
import org.lsk.pfc.scsim.model.util.ConstantKeys;

/**
 * Basic multi-agent system of the simulation.
 * 
 * @author Pablo Díaz Fernández
 * 
 */
public abstract class MultiAgentSystem {

	/**
	 * Name of this Multi Agent System.
	 */
	private String masName;
	/**
	 * Instance of the control agent.
	 */
	private AgentController controlAgent;
	/**
	 * Instance of the forecasting agent.
	 */
	private List<AgentController> forecastingAgentList;
	/**
	 * Instance of the information agent.
	 */
	private AgentController informationAgent;
	/**
	 * Instance of the user agent.
	 */
	private AgentController userAgent;

	/**
	 * List of providers of this slave of the chain.
	 */
	private List<String> providers;

	/**
	 * Constructor that initializes object attributes.
	 * 
	 * @param masName
	 *            The MAS name to set.
	 * @param cc
	 *            {@link ContainerController} The Jade Container Controller
	 *            needed to create agents.
	 * 
	 * @throws MASCreationException
	 *             Exception creating agents
	 */
	protected MultiAgentSystem(final String masName,
	        final ContainerController cc) throws MASCreationException {
		this.masName = masName;
		this.forecastingAgentList = new ArrayList<AgentController>();
		try {
			informationAgent = cc.createNewAgent(masName
			        + ConstantKeys.IA_SUFFIX,
			        InformationAgent.class.getCanonicalName(),
			        new Object[] { masName });
			userAgent = cc.createNewAgent(masName + ConstantKeys.UA_SUFFIX,
			        UserAgent.class.getCanonicalName(), null);
		} catch (StaleProxyException e) {
			throw new MASCreationException(masName, e);
		}
	}

	/**
	 * Start all agents.
	 * 
	 * @throws AgentException
	 *             Exception starting the agents
	 */
	public final void startAgents() throws AgentException {
		try {
			controlAgent.start();
			informationAgent.start();
			userAgent.start();
		} catch (StaleProxyException e) {
			throw new AgentException(masName, e);
		}
	}

	/**
	 * Gets the masName.
	 * 
	 * @return the masName
	 */
	public final String getMasName() {
		return masName;
	}

	/**
	 * Sets the controlAgent.
	 * 
	 * @param controlAgent
	 *            the controlAgent to set
	 */
	public final void setControlAgent(final AgentController controlAgent) {
		this.controlAgent = controlAgent;
	}

	/**
	 * Adds a forecasting agent to the MAS.
	 * 
	 * @param agent
	 *            Forecasting agent to be added.
	 */
	public final void addForecastingAgent(final AgentController agent) {
		this.forecastingAgentList.add(agent);
	}
}
